package com.snowfox;

import io.github.centrifugal.centrifuge.Client;
import io.github.centrifugal.centrifuge.ConnectingEvent;
import io.github.centrifugal.centrifuge.DuplicateSubscriptionException;
import io.github.centrifugal.centrifuge.JoinEvent;
import io.github.centrifugal.centrifuge.LeaveEvent;
import io.github.centrifugal.centrifuge.Options;
import io.github.centrifugal.centrifuge.EventListener;
import io.github.centrifugal.centrifuge.ServerJoinEvent;
import io.github.centrifugal.centrifuge.ServerLeaveEvent;
import io.github.centrifugal.centrifuge.ServerPublicationEvent;
import io.github.centrifugal.centrifuge.ServerSubscribedEvent;
import io.github.centrifugal.centrifuge.ServerSubscribingEvent;
import io.github.centrifugal.centrifuge.ServerUnsubscribedEvent;
import io.github.centrifugal.centrifuge.Subscription;
import io.github.centrifugal.centrifuge.SubscriptionEventListener;
import io.github.centrifugal.centrifuge.ConnectedEvent;
import io.github.centrifugal.centrifuge.DisconnectedEvent;
import io.github.centrifugal.centrifuge.ErrorEvent;
import io.github.centrifugal.centrifuge.MessageEvent;
import io.github.centrifugal.centrifuge.SubscribingEvent;
import io.github.centrifugal.centrifuge.PublicationEvent;
import io.github.centrifugal.centrifuge.SubscriptionErrorEvent;
import io.github.centrifugal.centrifuge.SubscribedEvent;
import io.github.centrifugal.centrifuge.SubscriptionOptions;
import io.github.centrifugal.centrifuge.UnsubscribedEvent;
import lombok.extern.slf4j.Slf4j;

import static java.nio.charset.StandardCharsets.UTF_8;

@Slf4j
public class Main {
    public static void main(String[] args) {
        log.info("App is running");

        EventListener listener = new EventListener() {
            @Override
            public void onConnected(Client client, ConnectedEvent event) {
                System.out.printf("已连接到客户端id %s%n", event.getClient());
            }

            @Override
            public void onConnecting(Client client, ConnectingEvent event) {
                System.out.printf("连接: %s%n", event.getReason());
            }

            @Override
            public void onDisconnected(Client client, DisconnectedEvent event) {
                System.out.printf("断开连接 %d %s%n", event.getCode(), event.getReason());
            }

            @Override
            public void onError(Client client, ErrorEvent event) {
                System.out.printf("连接错误: %s%n", event.getError().toString());
            }

            @Override
            public void onMessage(Client client, MessageEvent event) {
                String data = new String(event.getData(), UTF_8);
                System.out.println("收到的消息: " + data);
            }

            @Override
            public void onSubscribed(Client client, ServerSubscribedEvent event) {
                System.out.println("服务器端订阅: " + event.getChannel() + ", 复位 " + event.getRecovered());
            }

            @Override
            public void onSubscribing(Client client, ServerSubscribingEvent event) {
                System.out.println("服务器端订阅: " + event.getChannel());
            }

            @Override
            public void onUnsubscribed(Client client, ServerUnsubscribedEvent event) {
                System.out.println("服务器端取消订阅: " + event.getChannel());
            }

            @Override
            public void onPublication(Client client, ServerPublicationEvent event) {
                String data = new String(event.getData(), UTF_8);
                System.out.println("服务器端发布: " + event.getChannel() + ": " + data);
            }

            @Override
            public void onJoin(Client client, ServerJoinEvent event) {
                System.out.println("服务器端加入: " + event.getChannel() + " 来自客户端 " + event.getInfo().getClient());
            }

            @Override
            public void onLeave(Client client, ServerLeaveEvent event) {
                System.out.println("服务器端休假: " + event.getChannel() + " 来自客户端 " + event.getInfo().getClient());
            }
        };

        Options opts = new Options();
        opts.setName("Java Client");
        // 更换为 auth接口的 token 值
        opts.setToken("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIyMjUifQ.vzkhw7nx5TwQxd3ElaJWfIq8pbcPJRFhum-3AhCOk7M");

        // 更换为实际的推送服务器地址
        Client client = new Client("ws://hnlyx.duckdns.org:9090/connection/websocket", opts, listener);
        client.connect();

        SubscriptionEventListener subListener = new SubscriptionEventListener() {
            @Override
            public void onSubscribed(Subscription sub, SubscribedEvent event) {
                System.out.println("订阅 " + sub.getChannel() + ", 恢复 " + event.getRecovered());
            }

            @Override
            public void onSubscribing(Subscription sub, SubscribingEvent event) {
                System.out.printf("订阅: %s%n", event.getReason());
            }

            @Override
            public void onUnsubscribed(Subscription sub, UnsubscribedEvent event) {
                System.out.println("取消订阅 " + sub.getChannel() + ", 原因: " + event.getReason());
            }

            @Override
            public void onError(Subscription sub, SubscriptionErrorEvent event) {
                System.out.println("subscription error " + sub.getChannel() + " " + event.getError().toString());
            }

            @Override
            public void onPublication(Subscription sub, PublicationEvent event) {
                String data = new String(event.getData(), UTF_8);
                System.out.println("message from " + sub.getChannel() + " " + data);
            }

            @Override
            public void onJoin(Subscription sub, JoinEvent event) {
                System.out.println("client " + event.getInfo().getClient() + " joined channel " + sub.getChannel());
            }

            @Override
            public void onLeave(Subscription sub, LeaveEvent event) {
                System.out.println("client " + event.getInfo().getClient() + " left channel " + sub.getChannel());
            }
        };

        Subscription sub;
        try {
            // 分组频道： group_ 拼接 用户组编号
            SubscriptionOptions so = new SubscriptionOptions();
            sub = client.newSubscription("group_1", so, subListener);
        } catch (DuplicateSubscriptionException e) {
            e.printStackTrace();
            return;
        }
        sub.subscribe();

        Subscription subBroadcast;
        try {
            // 广播频道 broadcast
            SubscriptionOptions soBroadcast = new SubscriptionOptions();
            subBroadcast = client.newSubscription("broadcast", soBroadcast, subListener);
        } catch (DuplicateSubscriptionException e) {
            e.printStackTrace();
            return;
        }
        subBroadcast.subscribe();

    }
}